<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Parent class for eMail.
 *
 * @package   block_email_list
 * @access    public
 * @author    Toni Mas <toni.mas@uib.dot.es>
 * @copyright 2009 by <toni.mas at uib dot es>
 * @license   The source code packaged with this file is Free Software, Copyright (C) 2009 by <toni.mas at uib dot es>.
 *            It's licensed under the AFFERO GENERAL PUBLIC LICENSE unless stated otherwise.
 *            You can get copies of the licenses here:
 *                http://www.fsf.org/licensing/licenses/agpl-3.0.html
 *            AFFERO GENERAL PUBLIC LICENSE is also included in the file called "COPYING".
 */

/**
 * eMail class
 *
 * @copyright 2009 by Toni Mas <toni.mas at uib dot es>
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AFFERO GENERAL PUBLIC LICENSE
 */
class eMail {
    /**
     * eMail Id.
     * @access protected
     * @var int $id eMail id
     */
    protected $id = null;

    /**
     * Writer Id (User Id).
     * @access public
     * @var int $userid Writer.
     */
    public $userid;

    /**
     * Course Id to which it belongs email
     * @access public
     * @var int $course Course id.
     */
    public $course;

    /**
     * eMail unix timestamp creation.
     * @access public
     * @var int $timecreated TimeStamp
     */
    public $timecreated;

    /**
     * Subject.
     * @access public
     * @var string $subject Subject of email
     */
    public $subject;

    /**
     * Body.
     * @access public
     * @var text $body Body of email
     */
    public $body;

    /**
     * All attachments
     * @access public
     * @var array $attachments Attachments
     */
    public $attachments = array();

    /**
     * Users that this email has send by type to.
     * @access protected
     * @var array $to To
     */
    protected $to = array();

    /**
     * Users that this email has send by type cc.
     * @access protected
     * @var array $cc CC
     */
    protected $cc = array();

    /**
     * Users that this email has send by type bcc.
     * @access protected
     * @var array $bcc BCC
     */
    protected $bcc = array();

    /**
     * Mark if eMail has reply, reply all or forward
     * @access public
     * @var string $type Reply, reply all or forward
     */
    public $type = null;

    /**
     * Mark if eMail is save in draft
     * @access public
     * @var boolean $draft Is draft?
     */
    public $draft = false;


    /**
     * Old eMail Id when this send by reply or reply all message.
     * @access private
     * @var int $oldmailid Old mail id, for update.
     */
    private $oldmailid = 0;

    /**
     * eMail Id of parent. If one mail has replied, set mailid in a children mail, because
     * know this parent. View CONTRIB-1720
     * @var int $respondedid Mail Id Parent of this, when Parent has replied.
     */
    public $respondedid = 0;

    /**
     * Old attachments if mail have forward or draft
     */
    public $oldattachments = array();

    /**
     * The class constructor.
     *
     * @access public
     * @version 1.0
     * @uses $USER
     */
    function __construct() {
        global $USER;

        // Init all @var
        $this->subject = '';
        $this->body    = '';
        $this->userid  = $USER->id; // by default, insert USER id.
        $this->course  = SITEID;    // by default, insert SITEID.
    }

    /**
     * Set subject.
     *
     * @access public
     * @version 1.0
     * @param string $subject Subject
     * @return boolean Whether the subject was successfully set
     */
    function set_subject($subject) {

        if (!empty( $subject ) ) {
            // Clean text
            $this->subject = clean_text($subject);
            return true;
        } else {
            // Display error
            print_error(get_string('nosubject', 'block_email_list'));
        }
        return false;
    }

    /**
     * Set body.
     *
     * @access public
     * @version 1.0
     * @param text $body Body
     * @return boolean Whether the body was successfully set
     */
    function set_body($body = '') {
        global $CFG, $USER;

        if (empty($body) ) {
            $this->body = ''; // Define one value
        } else {
            $context = context_course::instance($this->course);
            $body = clean_text($body);
            $this->body = (!empty($USER->htmleditor) && !empty($CFG->htmleditor))
                          ? nl2br($body) // BJB101104&22: fixes non-HTML editors
                          : $body;
        }
        return true;
    }

    /**
     * This function add attahcments at email
     *
     * @access public
     * @version 1.0
     * @param array $attachments Attachments
     * @return boolean Successful or not.
     */
    function set_attachments($attachments) {

        if (! empty($attachments)) {

            if (is_array($attachments)) {
                $this->attachments = $attachments;
                return true;
            } else {
                $this->attachments = array($attachments);
                return true;
            }
        }
        return false;
    }

    /**
     * Set users send type to
     *
     * @access public
     * @version 1.0
     * @param array $to To
     * @return void
     */
    function set_sendusersbyto($to=array()) {

        $this->to = maillist_to_users($to);
    }

    /**
     * Set users send type cc
     *
     * @access public
     * @version 1.0
     * @param array $cc CC
     * @return void
     */
    function set_sendusersbycc($cc=array()) {

        $this->cc = maillist_to_users($cc, $this->to);
    }

    /**
     * Set users send type bcc
     *
     * @access public
     * @version 1.0
     * @param array $bcc BCC
     * @return void
     */
    function set_sendusersbybcc($bcc=array()) {

        $this->bcc = maillist_to_users($bcc, $this->to, $this->cc);
    }

    /**
     * This function show if user exist, confirmed and not deleted. Only User id.
     *
     * @access private
     * @version 1.0
     * @param int $userid User Id.
     * @return boolean User exist and this is confirmed, return true, else false.
     * @uses $DB
     */
    function user_exists($userid) {
        global $DB;

        if (!empty($userid) ) {
            // User exist

            if ($user = $DB->get_record('user', array('id' => $userid))) {
                // User confirmed and not deleted

                if ($user->confirmed and !$user->deleted) {
                    return true;
                }
                // Debugging
                debugging('User Id '.$userid. ' is not confirmed or deleted');
            }
            // Debugging
            debugging('User Id '.$userid. ' don\'t exist');
        }

        // Debugging
        debugging('User Id is empty');

        return false;
    }

    /**
     * This function show if course exist. Only course id.
     *
     * @access private
     * @version 1.0
     * @param int $courseid Course Id.
     * @return boolean Course exist return true, else false.
     * @uses $DB
     * @todo User access to this course is showed in other level.
     */
    function course_exists($courseid) {
        global $DB;

        if (!empty($courseid) ) {
            // Course exist

            if ($DB->get_record('course', array('id' => $courseid))) {
                return true;
            }
            // Debugging
            debugging('Course Id '.$courseid. ' don\'t exist');

        }
        // Debugging
        debugging('Course Id is empty');
        return false;
    }

    /**
     * This function insert new record on email_mail.
     *
     * @access private
     * @version 1.0
     * @return void
     * @uses $CFG
     * @uses $DB
     */
    function insert_mail_record() {

        global $CFG, $DB;

        $mail = new object();

        // Has defined userid? User exist?
        if ($this->user_exists($this->userid)) {
            $mail->userid = $this->userid;
        } else {
            print_error('failinsertrecord', 'block_email_list', $CFG->wwwroot
                       .'/blocks/email_list/email/index.php?id='.$this->course);
        }

        // Course exist and userid can access?
        if ($this->course_exists($this->course)) {
            $mail->course = $this->course;
        } else {
            print_error('failinsertrecord', 'block_email_list', $CFG->wwwroot
                       .'/blocks/email_list/email/index.php?id='.$this->course);
        }

        // Apply default values
        $mail->subject = $this->subject;
        $mail->body = $this->body;

        // Assign default time created value.
        if (empty($this->timecreated)) {
            $this->timecreated = time();
        }
        $mail->timecreated = $this->timecreated;
        $mail->respondedid = $this->respondedid; // If reply/reply all, save parent id.


        if (! $this->id = $DB->insert_record('block_email_list_mail', $mail)) {
            print_error('failinsertrecord', 'block_email_list', $CFG->wwwroot
                       .'/blocks/email_list/email/index.php?id='.$this->course);
        }
    }

    /**
     * This function update record on email_mail.
     *
     * @access private
     * @version 1.0
     * @return void
     * @uses $DB
     */
    function update_mail_record() {
        global $CFG,$DB;

        $mail   = new object();
        $error  = ($this->oldmailid <= 0);
        $error |= (! $this->user_exists($this->userid));
        $error |= (! $this->course_exists($this->course));

        if (! $error) {
            $mail->id          = $this->oldmailid;
            $mail->userid      = $this->userid;
            $mail->course      = $this->course;
            $mail->subject     = $this->subject;
            $mail->body        = $this->body;
            $mail->timecreated = time();

            $error = $DB->update_record('block_email_list_mail', $mail);
        }

        if (! $error) {
            print_error('failupdaterecord', 'block_email_list', $CFG->wwwroot
                       .'/blocks/email_list/email/index.php?id='.$this->course);
        }
    }

    /**
     * This function send this eMail to respective users.
     * Active the corresponding flag to user sent.
     * Add new mail in table.
     * Add all references in send table.
     *
     * @access public
     * @version 1.0
     * @return boolean Success or not.
     * @uses $COURSE
     * @uses $DB
     * @uses $OUTPUT
     * @uses $USER
     */
    function send() {
        global $COURSE, $DB, $OUTPUT, $USER;

        // Mark answered old mail
        if ($this->type === EMAIL_REPLY || $this->type === EMAIL_REPLYALL ) {
            $this->mark_to_answered($USER->id, $COURSE->id, $this->oldmailid, true);
        }

        // Mark answered parent mail (if it's a reply or reply all)
        if ($this->respondedid > 0 ) {
            $this->mark_to_answered($USER->id, $COURSE->id, $this->respondedid, true);
        }

        if (! $this->id || $this->type === EMAIL_FORWARD
           || $this->type === EMAIL_REPLY || $this->type === EMAIL_REPLYALL) {
            $this->timecreated = time();
            // Insert record
            $this->insert_mail_record();
        } else {
            // Update record
            $this->update_mail_record(); // Abans s'ha d'haver introduït el ID del correu que es vol actualitzar!!
        }

        if (! $this->reference_mail_folder($this->userid, EMAIL_SENDBOX) ) {
            return false;
        }

        // If mail has saved in draft, delete this reference.
        if ($folderdraft = email_get_root_folder($this->userid, EMAIL_DRAFT) ) {

            if ($foldermail = email_get_reference_to_foldermail($this->id, $folderdraft->id) ) {

                if (! $DB->delete_records('block_email_list_foldermail', array('id' => $foldermail->id))) {
                    print_error('failremovingdraft', 'block_email_list');
                }
            }
        }

        // Add attachments
        if ($this->attachments || $this->oldattachments) {

            if (! $this->add_attachments()) {
                echo $OUTPUT->notification(get_string('failuploadingattachments', 'block_email_list'));
            }
        }

        // If mail already exist ... (in draft)
        if ($this->id ) {
            // Drop all records, and insert all again.
            if (! $DB->delete_records('block_email_list_send', array('mailid' => $this->id))) {
                return false;
            }
        }

        // Prepare send mail
        $send = new stdClass();
        $send->userid     = $this->userid;
        $send->course     = $this->course;
        $send->mailid    = $this->id;
        $send->readed    = 0;
        $send->sended     = 1;
        $send->answered = 0;

        $types = array('to', 'cc', 'bcc');

        foreach ($types as $type) {

            if (! empty($this->$type)) {

                // Insert mail into send table, for all senders users.
                foreach ($this->$type as $userid) {

                    // In this moment, create if no exist this root folders
                    email_create_parents_folders($userid);

                    $send->userid = $userid;
                    $send->type   = $type;

                    if (! $DB->insert_record('block_email_list_send', $send)) {
                        print_error('failinsertsendrecord', 'block_email_list');
                        return false;
                    }

                    // Add reference to corresponding user
                    if (! $this->reference_mail_folder($userid, EMAIL_INBOX)) {
                        return false;
                    }
                }
            }
        }

        add_to_log($this->course, 'email_list', 'add mail', 'sendmail.php', "$this->subject", 0, $this->userid);

        return $this->id;
    }

    /**
     * This functions add mail in user draft folder.
     * Add new mail in table.
     * Add all references in table send.
     *
     * @access public
     * @version 1.0
     * @param int $mailid Old mail ID
     * @return boolean Success/Fail
     * @uses $DB
     * @todo Finish documenting this function
     **/
    function save($mailid=null) {
        global $DB, $OUTPUT;

        $this->timecreated = time();
        $types = array('to', 'cc', 'bcc');

        if (! $mailid) {

            $this->insert_mail_record();

            // Prepare send mail
            $send = new stdClass();
            $send->userid = $this->userid;
            $send->course = $this->course;
            $send->mailid = $this->id;
            $send->readed = 0;
            $send->sended = 0; // Important
            $send->answered = 0;

            foreach ($types as $type) {

                if (! empty($this->$type)) {

                    // Insert mail into send table, for all senders users.
                    foreach ($this->$type as $userid) {

                        // In this moment, create if no exist this root folders
                        email_create_parents_folders($userid);

                        $send->userid = $userid;
                        $send->type   = $type;

                        if (! $DB->insert_record('block_email_list_send', $send)) {
                            print_error('failinsertsendrecord', 'block_email_list');
                            return false;
                        }
                    }
                }
            }

            if (! $this->reference_mail_folder($this->userid, EMAIL_DRAFT) ) {
                print_error('failinsertrecord', 'block_email_list');
            }

        } else {
            $this->oldmailid = $mailid;

            $this->update_mail_record();

            // Drop all records, and insert all again.
            if ($DB->delete_records('block_email_list_send', array('mailid' => $mailid))) {

                // Prepare send mail
                $send = new stdClass();
                $send->userid = $this->userid;
                $send->course = $this->course;
                $send->mailid = $mailid;
                $send->readed = 0;
                $send->sended = 0; // Important
                $send->answered = 0;

                // Now, I must verify the users who sended mail, in case they have changed.
                foreach ($types as $type) {

                    if (! empty($this->$type) ) {

                        // Insert mail into send table, for all senders users.
                        foreach ($this->$type as $userid) {

                            $send->userid = $userid;
                            $send->type   = $type;

                            if (! $DB->insert_record('block_email_list_send', $send)) {
                                print_error('failinsertsendrecord', 'block_email_list');
                                return false;
                            }
                        }
                    }
                }
            }
        }

        // Add attachments
        if ($this->attachments or $this->oldattachments ) {

            if (! $this->add_attachments() ) {
                echo $OUTPUT->notification('Fail uploading attachments');
            }
        }

        add_to_log($this->course, 'email_list', 'add mail in draft', 'sendmail.php',
                   "$this->subject", 0, $this->userid);

        return $this->id;
    }

    /**
     * This function remove eMail, if this does in TRASH folder remove of BBDD else move to TRASH folder.
     *
     * @access public
     * @version 1.0
     * @param int  $userid   User Id
     * @param int  $courseid Course Id
     * @param int  $folderid Folder Id
     * @param bool $silent   Show or not show messages
     * @return bool Success/Fail
     * @uses $DB
     * @uses $OUTPUT
     * @todo Finish documenting this function
     */
    function remove($userid, $courseid, $folderid, $silent=false) {
        global $DB, $OUTPUT;

        // First, show if folder remove or not

        $deletemails = false;
        $success = true;

        if (email_isfolder_type($DB->get_record('block_email_list_folder', array('id' => $folderid)), EMAIL_TRASH) ) {
            $deletemails = true;
        }

        // FIXME: Esborrar els attachments quan no hagi cap referència al mail


        // If delete definity mails ...
        if ($deletemails ) {
            $criteria = array('mailid' => $this->id, 'userid' => $userid, 'course' => $courseid);
            // Delete reference mail
            if (! $DB->delete_records('block_email_list_send', $criteria)) {
                return false;
            }
        } else {
            // Get remove folder user
            $removefolder = email_get_root_folder($userid, EMAIL_TRASH);

            // Get actual folder
            $actualfolder = email_get_reference_to_foldermail($this->id, $folderid);

            if ($actualfolder) {
                // Move mails to trash
                if (! email_move_to_folder($this->id, $actualfolder->id, $removefolder->id)) {
                    $success = false;
                } else {
                    // Mark the message as read
                    $criteria = array('mailid' => $this->id, 'userid' => $userid, 'course' => $courseid);
                    $DB->set_field('block_email_list_send', 'readed', 1, $criteria); //Thanks Ann
                }
            } else {
                $success = false;
            }
        }

        // Notify
        if ($success ) {
            add_to_log($this->course, 'email_list', 'remove mail', '', 'Remove '.$this->subject, 0, $this->userid);

            if (! $silent ) {
                echo $OUTPUT->notification(get_string('removeok', 'block_email_list'), 'notifysuccess');
            }
            return true;
        } else {

            if (! $silent ) {
                echo $OUTPUT->notification(get_string('removefail', 'block_email_list'));
            }
            return false;
        }
    }

    /**
     * This function mark eMail as answered.
     *
     * @access protected
     * @version 1.0
     * @param int  $userid   User Id
     * @param int  $courseid Course Id
     * @param int  $mailid   Mark as read external eMail
     * @param bool $silent   Display success.
     * @return bool Success/Failure
     * @uses $DB
     * @uses $OUTPUT
     */
    function mark_to_answered($userid, $courseid, $mailid=0, $silent=false) {
        global $DB, $OUTPUT;
        // Status
        $success = true;

        $criteria = array('userid' => $userid, 'course' => $courseid);

        if ($mailid > 0) {
            $criteria['mailid'] = $mailid;

            // Mark answered
            if (! $DB->set_field('block_email_list_send', 'answered', 1, $criteria)) {
                $success = false;
            }

        } else if ($this->id > 0 ) {
            $criteria['mailid'] = $this->id;

            // Mark answered
            if (! $DB->set_field('block_email_list_send', 'answered', 1, $criteria)) {
                $success = false;
            }
        } else {
            $success = false;
        }

        if (!$silent && !$success ) {
            echo 'toni:'.$this->id;
            echo $OUTPUT->notification(get_string('failmarkanswered', 'block_email_list'));
            die;
        }
        return $success;
    }

    /**
     * This function mark mails to read.
     *
     * @access protected
     * @version 1.0
     * @param int  $userid User Id
     * @param int  $course Course Id
     * @param bool $silent Show or not show messages
     * @return bool Success/Fail
     * @uses $DB
     * @uses $OUTPUT
     * @todo Finish documenting this function
     **/
    function mark_to_read($userid, $course, $silent=false) {
        global $DB, $OUTPUT;
        $success = true;

        // Mark as read if eMail Id exist
        if ($this->id > 0 ) {
            $criteria = array('mailid' => $this->id, 'userid' => $userid, 'course' => $course);

            if (! $DB->set_field('block_email_list_send', 'readed', 1, $criteria)) {
                $success = false;
            }
        } else {
            $success = false;
        }

        if ($success) {

            if (! $silent ) {
                // Display success
                echo $OUTPUT->notification(get_string('toreadok', 'block_email_list'), 'notifysuccess');
            }
            return true;
        } else {

            if (! $silent ) {
                echo $OUTPUT->notification(get_string('failmarkreaded', 'block_email_list'));
            }
            return false;
        }
    }

    /**
     * This function mark mails to unread.
     *
     * @access protected
     * @version 1.0
     * @param int  $userid User Id
     * @param int  $course Course Id
     * @param bool $silent Show or not show messages
     * @return boolean Success/Fail
     * @uses $DB
     * @uses $OUTPUT
     **/
    function mark_to_unread($userid, $course, $silent=false) {
        global $DB, $OUTPUT;
        $success = true;

        // Mark as unread if eMail Id exist
        if ($this->id > 0 ) {
            $criteria = array('mailid' => $this->id, 'userid' => $userid, 'course' => $course);

            if (! $DB->set_field('block_email_list_send', 'readed', 0, $criteria)) {
                $success = false;
            }
        } else {
            $success = false;
        }

        // Display success
        if ($success) {

            if (! $silent) {
                // Display success
                echo $OUTPUT->notification(get_string('tounreadok', 'block_email_list'), 'notifysuccess');
            }
            return true;
        } else {

            if (! $silent) {
                echo $OUTPUT->notification(get_string('failmarkunreaded', 'block_email_list'));
            }
            return false;
        }

    }

    /**
     * This function insert reference mail <-> folder. There apply filters.
     *
     * @access private
     * @version 1.0
     * @param int    $userid     User Id
     * @param string $foldername Folder name
     * @return boolean Success/Fail
     * @uses $DB
     * @todo Finish documenting this function
     **/
    function reference_mail_folder($userid, $foldername) {
        global $DB;

        $foldermail = new stdClass();

        $foldermail->mailid = $this->id;

        $folder = email_get_root_folder($userid, $foldername);

        $foldermail->folderid = $folder->id;

        // Insert into inbox user
        if (! $DB->insert_record('block_email_list_foldermail', $foldermail)) {
            return false;
        }

        return true;

    }

    /**
     * This function add new files into mailid.
     *
     * @access protected
     * @version 1.0
     * @return string Array of all name attachments upload
     * @uses $CFG
     * @uses $DB
     * @uses $OUTPUT
     * @uses $USER
     */
    function add_attachments() {
        global $CFG, $DB, $OUTPUT, $USER;

        /// Note: $attachments is an array, who it's 5 sub-array in here.
        /// name, type, tmp_name. size, error who have an arrays.

        $empty_old = empty($this->oldattachments);
        $empty_new = empty($this->attachments);
        $is_error  = isset($this->attachments[0]['error']);
        $is_error4 = ($is_error && ($this->attachments[0]['error'] == 4));

        $usercontext = context_user::instance($USER->id);

        // Prevent errors
        if ($empty_old && ($empty_new || $is_error4) ) {
            return true;
        }

        // Get course for upload manager
        if (! $course = $DB->get_record('course', array('id' => $this->course))) {
            return '';
        }

        if (! $empty_new || $is_error4) {
            // Now, processing all attachments . . .
            $draftitemid = file_get_submitted_draft_itemid('attachments');
            file_prepare_draft_area($draftitemid, $usercontext->id, 'block_email_list',
                                    'attachments', $this->id);
            $this->set_attachments($draftitemid);

            file_save_draft_area_files($draftitemid, $usercontext->id, 'block_email_list', 'attachments', $this->id);
        }

        // Now, delete old corresponding files
        if (! $empty_old) {
            $fs          = get_file_storage();

            // Working in same email
            if ($this->type != EMAIL_FORWARD && $this->type != EMAIL_REPLY && $this->type != EMAIL_REPLYALL) {

                // Get files of mail
                $filehash    = array();
                $usercontext = context_user::instance($this->userid);

                $files = $fs->get_area_files($usercontext->id, 'block_email_list', 'attachments', $this->id);

                if ($files) {

                    // Process all attachments
                    foreach ($files as $key => $file) {
                        // Get path of file
                        $attach = $file->get_filepath() .'/'. $file->get_filename();

                        $attachments[] = $attach;
                        $filehash[$attach] = $key;
                    }
                }

                if ($diff = array_diff($attachments, $this->oldattachments)) {

                    foreach ($diff as $attachment) {
                        $files[$filehash[$attachment]]->delete(); // Drop file
                    }
                }

            } else if ($this->type === EMAIL_FORWARD) {    // Copy $this->oldattachments in this new email

                $olduserid = $DB->get_field('block_email_list_mail', 'userid', array('id' => $this->oldmailid));
                $oldusercontext = context_user::instance($olduserid);
                $files = $fs->get_area_files($oldusercontext->id, 'block_email_list', 'attachments', $this->oldmailid);
                $file_record = array('contextid' => $usercontext->id, 'itemid' => $this->id);

                foreach ($this->oldattachments as $attachment) {
                    foreach ($files as $file) {
                        $filename = $file->get_filepath() . $file->get_filename();
                        if ($filename == $attachment) {
                            $fs->create_file_from_storedfile($file_record, $file);
                        }
                    }
                }
            }
        }
        return true;
    }

    /**
     * This functions create upload directory if it's necessary.
     * and return path it.
     *
     * @access private
     * @version 1.0
     * @return bool|string Return the upload file path.
     **/
    function get_file_area() {

        // First, showing if have path to save mails
        if (!$name = $this->get_file_area_name()) {
            return false;
        }

        return make_upload_directory($name);
    }

    /**
     * This function return upload attachment path.
     *
     * @access private
     * @version 1.0
     * @return string Path on save upload files
     * @uses $DB Gets record
     * @todo Finish documenting this function
     * @deprecated No longer needed since Moodle 2.0
     **/
    function get_file_area_name() {
        global $DB;

        //Get mail
        if (! $DB->get_record('block_email_list_mail', array('id' => $this->id))) {
            return false;
        }

        return "$this->course/email/$this->userid/$this->id";
    }

    /**
     * This functions return attachments of mail.
     *
     * @access public
     * @version 1.0
     * @return array All attachments
     * @uses $CFG Needs dirroot
     * @todo Finish documenting this function
     **/
    function get_attachments() {
        global $CFG;

        // Necessary library for this function
        include_once($CFG->dirroot.'/lib/filelib.php');

        // Get attachments mail path
        $fs    = get_file_storage();
        $usercontext = context_user::instance($this->userid);
        $files = $fs->get_area_files($usercontext->id, 'block_email_list', 'attachments', $this->id);

        // Get attachments mail path
        $basedir = $this->get_file_area();
        $attachment = new stdClass();
        $attachments = array(); // BJB101025: fix Undefined variable error

        // Get files of mail
        if ($files) {

            // Process all attachments
            foreach ($files as $file) {
                // Skip directories, they shouldn't even be here
                if ($file->is_directory()) {
                    continue;
                }

                // Get path of file
                $attachment->path = $file->get_filepath();
                $attachment->name = $file->get_filename();

                // Path and filename of attachment is a hash in Moodle 2
                $contenthash = $file->get_contenthash();
                $attachment->contenthash = $contenthash;
                $attachment->path = 'filedir/'.substr($contenthash,0,2).'/'.substr($contenthash,2,2);

                $attachments[] = (PHP_VERSION < 5) ? $attachment : clone($attachment);    // Thanks Ann
            }
        }

        return $attachments;
    }

    /**
     * This funcion return formated fullname of user. ALLWAYS return firstname lastname.
     *
     * @access protected
     * @version 1.0
     * @param object $user     User
     * @param bool   $override Override
     * @return string User full name
     */
    function fullname($user, $override=false) {

        // Drop all semicolon apears. (Js errors when select contacts)
        return str_replace(',', '', fullname($user, $override));
    }

    /**
     * Function for define new eMail, with this data
     *
     * @access public
     * @version 1.0
     * @param object|int $email eMail
     * @return void
     * @uses $DB
     */
    function set_email($email) {
        global $DB;

        if (! empty($email) ) {

            if (is_object($email) ) {
                $this->id = $email->id;
                $this->subject = $email->subject;
                $this->body = $email->body;
                $this->timecreated = $email->timecreated;

                // Get writer
                if (! isset($email->writer) ) {
                    $this->userid = $email->userid;
                } else {
                    $this->userid = $email->writer;
                }
                $this->course = $email->course;

            } else if (is_int($email) ) {

                if ($mail = $DB->get_record('block_email_list_mail', array('id' => $email)) ) {
                    $this->id = $mail->id;
                    $this->subject = $mail->subject;
                    $this->body = $mail->body;
                    $this->timecreated = $mail->timecreated;
                    $this->userid = $mail->userid;
                    $this->course = $mail->course;
                    $this->respondedid = $mail->respondedid;
                }
            }
        }

    }

    /**
     * Set Writer
     *
     * @access public
     * @version 1.0
     * @param int $userid Writer
     * @return bool Success/Failure
     * @uses $USER
     */
    function set_writer($userid) {
        global $USER;

        // Security issues
        if (isset( $USER->id ) ) {

            if ($USER->id != $userid or !$userid) {
                // Display error
                print_error('incorrectuserid', 'block_email_list');
                return false;
            }
        }

        // Assign userid - FIXME: If user don't exist¿?
        $this->userid = $userid;
        return true;
    }

    /**
     * Get Writer
     *
     * @access public
     * @version 1.0
     * @return int User Id
     */
    function get_writer() {
        return $this->userid;
    }

    /**
     * Get full name of writer.
     *
     * @access public
     * @version 1.0
     * @param boolean $override Override
     * @return string Writer full name
     * @uses $DB Gets record
     */
    function get_fullname_writer($override=false) {
        global $DB;

        if ($user = $DB->get_record('user', array('id' => $this->userid)) ) {
            return $this->fullname($user, $override);
        } else {
            return ''; // User not found
        }
    }

    /**
     * Get format string of all fullnames users send.
     *
     * @access public
     * @version 1.0
     * @param string  $type     Type of email (to, cc or bcc)
     * @param boolean $override Override
     * @return string Contain user who writed mails
     * @uses $DB Gets records
     * @todo Finish documenting this function
     */
    function get_users_send($type='', $override=false) {
        global $DB;
        // Get send's

        if (isset($this->id) ) {
            $values = array('mailid' => $this->id);

            if ($type === 'to' || $type === 'cc' || $type === 'bcc' || $type === 'to_ext') {
                $values['type'] = $type;

                if (! $sendbox = $DB->get_records('block_email_list_send', $values)) {
                    return false;
                }
            } else {

                if (! $sendbox = $DB->get_records('block_email_list_send', $values) ) {
                    return false;
                }
            }

            $users = '';

            foreach ($sendbox as $sendmail) {

                if ($type === 'to_ext' || !empty($sendmail->toext)) {
                    $users .= $sendmail->toext;
                } else {
                    // Get user
                    if ($user = $DB->get_record('user', array('id' => $sendmail->userid)) ) {
                        $users .= $this->fullname($user, $override) .', ';
                    }
                }
            }

            if ($type !== 'to_ext' && empty($sendmail->toext)) {
                // Delete 2 last characters
                $count = strlen($users);
                $users = substr($users, 0, $count-2);
            }
            return $users;
        } else {
            return get_string('neverusers', 'block_email_list');
        }
    }

    /**
     * This function show if the user can read this mail.
     *
     * @access public
     * @version 1.0
     * @param object $user User.
     * @return boolean True or false if the user can read this mail.
     * @uses $DB
     * @todo Finish documenting this function
     */
    function can_readmail($user) {
        global $DB;

        // Writer
        if ($this->userid == $user->id ) {
            return true;
        }

        $senders = $DB->get_records('block_email_list_send', array('mailid' => $this->id));

        if ($senders) {

            foreach ($senders as $sender) {

                if ($sender->userid == $user->id) {
                    return true;
                }
            }
        }

        return false;

    }

    /**
     * This function return if mail is readed or not readed.
     *
     * @access public
     * @version 1.0
     * @param int $userid   User ID
     * @param int $courseid Course ID
     * @return boolean Success/Fail
     * @uses $DB
     * @todo Finish documenting this function
     **/
    function is_readed($userid, $courseid) {
        global $DB;

        $criteria = array('mailid' => $this->id, 'userid' => $userid, 'course' => $courseid);
        // Get mail
        if (! $send = $DB->get_record('block_email_list_send', $criteria) ) {
            return false;
        }

        // Return value
        return $send->readed;
    }

    /**
     * This function return true or false if mail has answered.
     *
     * @access public
     * @version 1.0
     * @param int $userid   User Id.
     * @param int $courseid Course ID.
     * @return boolean Success/Fail
     * @uses $DB
     * @todo Finish documenting this function
     **/
    function is_answered($userid, $courseid) {
        global $DB;

        $criteria = array('mailid' => $this->id, 'userid' => $userid, 'course' => $courseid);

        if (! $send = $DB->get_record('block_email_list_send', $criteria) ) {
            return false; // User Id is the writer (only apears in email_mail)
        }

        return $send->answered;
    }

    /**
     * This functions return if mail has attachments
     *
     * @access public
     * @version 1.0
     * @return boolean Success/Fail
     * @todo Finish documenting this function
     **/
    function has_attachments() {

        if (isset($this->id)) {

            // Get attachments mail path
            $fs    = get_file_storage();
            $usercontext = context_user::instance($this->userid);
            $files = $fs->get_area_files($usercontext->id, 'block_email_list', 'attachments', $this->id);

            // Count files of mail
            if (sizeof($files) > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * This functions prints attachments of mail
     *
     * @access private
     * @version 1.0
     * @param boolean $attachmentformat Print attachment formatting box (Optional)
     * @return boolean Success/Fail
     * @uses $CFG
     * @uses $OUTPUT
     * @todo Finish documenting this function
     **/
    function _get_format_attachments($attachmentformat=true) {
        global $CFG, $OUTPUT;

        // Necessary library for this function
        include_once($CFG->dirroot.'/lib/filelib.php');

        // Get strings
        $strattachment  = get_string('attachment', 'block_email_list');
        $strattachments = get_string('attachments', 'block_email_list');

        $html = '';

        // Get attachments mail path
        $fs = get_file_storage();
        $usercontext = context_user::instance($this->userid);

        // Get files of mail
        if ($files = $fs->get_area_files($usercontext->id, 'block_email_list', 'attachments', $this->id)) {

            if ($attachmentformat ) {
                $html .=  '<br /><br /><br />';
                $html .= '<hr width="80%" />';

                $result = count($files) == 1 ? $strattachment : $strattachments ;

                $html .= '<b>'. $result. '</b>';

                $html .= '<br />';
                $html .= '<br />';
            }
            // Process all attachments
            foreach ($files as $file) {
                // Get icon
                if ($file->is_directory()) {
                    continue;
                }
                $filename = $file->get_filename();
                $icon = basename(mimeinfo('icon', $filename), '.gif');
                $html .= '<img border="0" src="'. $OUTPUT->pix_url('/f/'. $icon)
                       .'" alt="icon" height="16" width="16" />';

                $html .= '&#160;';

                // Get path of file
                $filearea = $this->get_file_area_name();


                $ffurl = file_rewrite_pluginfile_urls('@@PLUGINFILE@@/', 'pluginfile.php', $usercontext->id,
                                                      'block_email_list', 'attachments', $this->id);

                $html .= '<a href="'.$ffurl.htmlspecialchars(str_replace('#', '%23', $filename)).'?forcedownload=1" target="blank">'.$filename.'</a>';
                $html .= '<br />';
            }

            if ($attachmentformat ) {
                $html .= '<br />';
            }
        }

        return $html;
    }

    /**
     * This function set old attachments.
     *
     * @access public
     * @version 1.0
     * @param array $oldattachments Old attachments
     * @return boolean Success/Fail
     */
    function set_oldattachments($oldattachments) {

        if (is_array($oldattachments)) {
            $this->oldattachments = $oldattachments;
            return true;

        } else if (is_string($oldattachments) ) {
            $this->oldattachments = array($oldattachments);
            return true;
        }

        return false;
    }

    /**
     * Set Course.
     *
     * @uses $COURSE
     * @access public
     * @version 1.0
     * @param int $courseid Course Id
     * @return boolean Success/Fail
     */
    function set_course($courseid) {
        global $COURSE;

        if (empty($courseid) and isset($COURSE->id)) {
            $this->course = $COURSE->id;

        } else if (empty($courseid)) {
            print_error('specifycourseid', 'block_email_list');
        }
        $this->course = $courseid;
        return true;
    }

    /**
     * Set type of mail.
     *
     * @access public
     * @version 1.0
     * @param string $type Type of email (Reply, reply all or forward)
     * @return boolean Success/Fail
     */
    function set_type($type) {
         $alloweds = array(EMAIL_REPLY, EMAIL_REPLYALL, EMAIL_FORWARD, EMAIL_EDITDRAFT);
        // Security control
        foreach ($alloweds as $allowed) {

            if ($type === $allowed) {
                $this->type = $allowed;
                return true;
            }
        }
        return false;
    }

    /**
     * Set old mail (if exit).
     *
     * @access public
     * @version 1.0
     * @param int $oldmailid Old mail id (Forward)
     * @return boolean Success/Fail
     */
    function set_oldmailid($oldmailid) {
        // Forbidden negative id's and zeros
        if ($oldmailid > 0) {
            $this->oldmailid = $oldmailid;
            return true;
        }
        return false;
    }

    /**
     * Set response mail id.
     *
     * @access public
     * @version 1.0
     * @param int $respondedid Response Mail Id. (Reply or Reply all parent)
     * @return boolean Success/Fail
     */
    function set_responded($respondedid) {
        $checktype = ($this->type === EMAIL_REPLY
                   OR $this->type === EMAIL_REPLYALL
                   OR $this->type === EMAIL_EDITDRAFT);
        // Only apply on reply, reply all, and negative id's and zeros has forbidden
        if ($respondedid > 0 AND $checktype) {
            $this->respondedid = $respondedid;
        }
        return false;
    }

    /**
     * Set mail ID (if exist).
     *
     * @access public
     * @version 1.0
     * @param int $id Mail id (Draft)
     * @return bool Whether id passed verification
     */
    function set_mailid($id) {
        // Forbidden negative id's and zeros
        if ($id > 0 ) {
            $this->id = $id;
            return true;
        }
        return false;
    }

    /**
     * This function display an eMail.
     *
     * @param int    $courseid        The course id
     * @param int    $folderid        The folder id
     * @param string $urlpreviousmail The url of the previous mail
     * @param string $urlnextmail     The url of the next mail
     * @param string $baseurl         The base url
     * @param object $user            The user object
     * @param bool   $override        Whether to override
     * @return void
     * @uses $CFG    Needs wwwroot
     * @uses $COURSE Needs id
     */
    function display($courseid, $folderid, $urlpreviousmail, $urlnextmail, $baseurl, $user, $override=false) {
        global $CFG, $COURSE;

        // SECURITY. User can read this mail?
        if (! $this->can_readmail($user) ) {
            print_error('dontreadmail', 'block_email_list', $CFG->wwwroot
                       .'/blocks/email_list/email/index.php?'.$baseurl);
        }

        // Now, mark mail as readed
        if (! $this->mark_to_read($user->id, $COURSE->id, true) ) {
            print_error('failmarkreaded', 'block_email_list');
        }

        echo $this->get_html($courseid, $folderid, $urlpreviousmail, $urlnextmail, $baseurl, $override);
    }

    /**
     * This function return an HTML code for display this eMail
     *
     * @param int    $courseid        The course id
     * @param int    $folderid        The folder id
     * @param string $urlpreviousmail The url of the previous mail
     * @param string $urlnextmail     The url of the next mail
     * @param string $baseurl         The base url
     * @param bool   $override        Whether to override
     * @return void
     * @uses $CFG  Needs wwwroot
     * @uses $DB
     * @uses $OUTPUT
     * @uses $USER
     */
    function get_html($courseid, $folderid, $urlpreviousmail, $urlnextmail, $baseurl, $override=false) {
        global $CFG, $DB, $OUTPUT, $USER;

        $html = '';

        $html .= '<table class="sitetopic" border="0" cellpadding="5" cellspacing="0" width="100%">';
        $html .= '<tr class="headermail">';
        $html .= '<td style="border-left: 1px solid black; border-top:1px solid black" width="7%" align="center">';

        // Get user picture
        $user = $DB->get_record('user', array('id' => $this->userid));
        $html .= $OUTPUT->user_picture($user);

        $html .= '</td>';

        $html .= '<td style="border-right: 1px solid black; border-top:1px solid black" align="left" colspan="2">';
        $html .= $this->subject;
        $html .= '</td>';

        $html .= '</tr>';

        $html .= '<tr>';

        $html .= '<td  style="border-left: 1px solid black; border-right: 1px solid black;'
               .' border-top:1px solid black" align="left" colspan="3">';
        $html .= '&nbsp;&nbsp;&nbsp;';
        $html .= '<b> '. get_string('from', 'block_email_list'). ':</b>&nbsp;';
        $html .= $this->get_fullname_writer($override);

        $html .= '</td>';
        $html .= '</tr>';

        $html .= '<tr>';

        $userstosendto = $this->get_users_send('to');

        $html .= '<td style="border-left: 1px solid black;" width="80%" align="left" colspan="2">';
        $html .= '&nbsp;&nbsp;&nbsp;';

        if ($userstosendto != '' ) {
            $html .= '<b> '. get_string('for', 'block_email_list') .':</b>&nbsp;';
            $html .= $userstosendto;
        }

        $userstosendtoext = $this->get_users_send('to_ext');

        if ($userstosendtoext != '') {
            $html .= (($userstosendto != '') ? ', '
            : '<b> '. get_string('for', 'block_email_list') .':</b>&nbsp;'). $userstosendtoext;
        }

        $html .= '</td>';

        $html .= '<td style="border-right: 1px solid black;" width="20%">';

        if ($urlnextmail or $urlpreviousmail ) {
            $html .= '&nbsp;&nbsp;&nbsp;||&nbsp;&nbsp;&nbsp;';
        }

        if ($urlpreviousmail ) {
            $html .= '<a href="view.php?'. $urlpreviousmail .'">' . get_string('previous', 'block_email_list') . '</a>';
        }

        if ($urlnextmail ) {

            if ($urlpreviousmail ) {
                $html .= '&nbsp;|&nbsp;';
            }
            $html .= '<a href="view.php?'. $urlnextmail .'">' . get_string('next', 'block_email_list').'</a>';
        }

        $html .= '&nbsp;&nbsp;';
        $html .= '</td>';
        $html .= '</tr>';

        $userstosendcc = $this->get_users_send('cc');

        if ($userstosendcc != '' ) {
            $html .= "<tr>\n"
                   . '  <td  style="border-left: 1px solid black; border-right: 1px solid black;"'
                   .         " align=\"left\" colspan=\"3\">\n&nbsp;&nbsp;&nbsp;\n"
                   . '    <b> ' . get_string('cc', 'block_email_list') .':</b>&nbsp;'. $userstosendcc ."\n"
                   . "  </td>\n"
                   ."</tr>\n";
        }

        // Drop users sending by bcc if user isn't writer
        if ($userstosendbcc = $this->get_users_send('bcc') != '' and $USER->id != $this->userid ) {
            $html .= "<tr>\n"
                   . '  <td  style="border-left: 1px solid black; border-right: 1px solid black;"'
                   .         " align=\"left\" colspan=\"3\">\n&nbsp;&nbsp;&nbsp;\n"
                   . '    <b> ' . get_string('bcc', 'block_email_list') .':</b>&nbsp;'. $userstosendbcc ."\n"
                   . "  </td>\n"
                   ."</tr>\n";
        }

        $html .= '<tr>';

        $html .= '<td style="border-left: thin solid black; border-right: 1px solid black"'
               .' width="60%" align="left" colspan="3">';
        $html .= '&nbsp;&nbsp;&nbsp;';

        $html .= '<b> '. get_string('date', 'block_email_list') . ':</b>&nbsp;';

        $html .= userdate($this->timecreated);

        $html .= '</td>';
        $html .= '</tr>';

        $html .= '<tr>';
        $html .= '<td style="border: 1px solid black" colspan="3" align="left">';
        $html .= '<br />';

        // Options for display body
        $options = new object();
        $options->filter = true;

        $html .= format_text($this->body, FORMAT_HTML, $options);

        if ($this->has_attachments()) {
            $html .= $this->_get_format_attachments();
        }

        $html .= '<br />';
        $html .= '<br />';
        $html .= '</td>';
        $html .= '</tr>';

        $html .= '<tr class="messagelinks">';
        $html .= '<td align="right" colspan="3">';

        $html .= '<a href="sendmail.php?'.$baseurl .'&amp;action='.EMAIL_REPLY.'"><b>'
               . get_string('reply', 'block_email_list'). '</b></a>';
        $html .= ' | ';
        $html .= '<a href="sendmail.php?'.$baseurl .'&amp;action='.EMAIL_REPLYALL.'"><b>'
               . get_string('replyall', 'block_email_list'). '</b></a>';
        $html .= ' | ';
        $html .= '<a href="sendmail.php?'.$baseurl .'&amp;action='.EMAIL_FORWARD.'"><b>'
               . get_string('forward', 'block_email_list'). '</b></a>';
        $html .= ' | ';
        $html .= '<a href="index.php?id='.$courseid .'&amp;mailid='.$this->id.'&amp;folderid='
               .$folderid.'&amp;action=removemail"><b>'. get_string('removemail', 'block_email_list'). '</b></a>';
        $html .= ' | ';

        $icon = '<img src="'.$CFG->wwwroot.'/blocks/email_list/email/images/printer.png"'
              .' height="16" width="16" alt="'.get_string('print', 'block_email_list').'" />';

        $html .= email_print_to_popup_window('link', '/blocks/email_list/email/print.php?courseid='
              .$courseid.'&amp;mailids='.$this->id, '<b>'.get_string('print', 'block_email_list')
              .'</b>'. $OUTPUT->spacer(array('height' => 1, 'width' => 3), false).$icon,
               get_string('print', 'block_email_list'), true);

        $html .= '</td>';

        $html .= '</tr>';
        $html .= '</table>';

        return $html;
    }

    public function get_id() {
        return $this->id;
    }

}
